home *** CD-ROM | disk | FTP | other *** search
/ HPAVC / HPAVC CD-ROM.iso / pc / ABUSESRC.ZIP / AbuseSrc / imlib / port / gl / video.c
Encoding:
C/C++ Source or Header  |  1995-08-04  |  8.8 KB  |  394 lines

  1.  
  2. #include <sys/time.h>
  3. #include <sys/types.h>
  4. #include <unistd.h>
  5. #include <signal.h>
  6. #include <stdlib.h>
  7. #include <stdio.h>
  8. #include <string.h>
  9. #include <sys/ipc.h>
  10. #include <sys/shm.h>
  11. #include <X11/Xlib.h>
  12. #include <X11/Xutil.h>
  13. #include <X11/Xatom.h>
  14. #include <X11/keysym.h>
  15. #include <X11/extensions/XShm.h>
  16. #include <GL/gl.h>
  17. #include <GL/glx.h>
  18. #include <GL/glu.h>
  19.  
  20. #include "globals.hpp"
  21. #include "system.h"
  22. #include "video.hpp"
  23. #include "dos.h"
  24. #include "macs.hpp"
  25. #include "image.hpp"
  26. #include "palette.hpp"
  27. #include "jmalloc.hpp"
  28.  
  29. image *screen=NULL;
  30. static ulong *frame_buffer=NULL;
  31.  
  32. uchar current_background=0;
  33.  
  34. typedef struct
  35. {
  36.     int input;
  37.     int output;
  38. } keymap_t;
  39.  
  40. static float xs;
  41. static float ys;
  42.  
  43. Display            *display;
  44. static Colormap            x_cmap;
  45. Window            mainwin;
  46. static GC                x_gc;
  47. static Visual            *my_visual;
  48. static XVisualInfo        *x_visinfo=0;
  49. //static XImage            *x_image;
  50. static int                x_screen;
  51.  
  52. static int            oktodraw = 0;
  53.  
  54. static unsigned char    *framebuffer=0;
  55.  
  56. static int verbose=0;
  57.  
  58. static short *jcspace=0;
  59.  
  60. static int            doGLX;
  61. static int glX_errorBase, glX_eventBase;
  62. static GLXContext glX_context;
  63.  
  64. static int            glX_scaled=0;
  65. static GLfloat            glX_scale_width;
  66. static GLfloat            glX_scale_height;
  67.  
  68. static int config_notify=0;
  69. static int config_notify_width;
  70. static int config_notify_height;
  71. int win_xres,win_yres;
  72.  
  73.  
  74. void PickVisual()
  75. {
  76.   int attribList1[] = { GLX_RGBA, GLX_DOUBLEBUFFER, GLX_RED_SIZE, 8,
  77.             GLX_BLUE_SIZE, 8, GLX_GREEN_SIZE, 8, None };
  78.   int attribList2[] = { GLX_RGBA, GLX_RED_SIZE, 8, GLX_GREEN_SIZE, 8,
  79.             GLX_BLUE_SIZE, 8, None };
  80.  
  81.   doGLX = glXQueryExtension(display, &glX_errorBase, &glX_eventBase);
  82.   if (!doGLX) { printf("OpenGL not supported\n"); exit(0); }
  83.  
  84.   x_visinfo = glXChooseVisual(display, x_screen, attribList1);
  85.   if (!x_visinfo)
  86.     x_visinfo = glXChooseVisual(display, x_screen, attribList2);
  87.   else
  88.     printf("double-buffered\n");
  89.  
  90.   if (!x_visinfo)
  91.   { printf("Could not chose an RGB visual.  Use X version.\n");  exit(0); }   
  92.   else
  93.     printf("single-buffered\n");
  94.  
  95.   my_visual = x_visinfo->visual;
  96. }
  97.  
  98.  
  99. // ========================================================================
  100. // makes a null cursor
  101. // ========================================================================
  102.  
  103. static Cursor CreateNullCursor(Display *display, Window root)
  104. {
  105.     Pixmap cursormask; 
  106.     XGCValues xgc;
  107.     GC gc;
  108.     XColor dummycolour;
  109.     Cursor cursor;
  110.  
  111.     cursormask = XCreatePixmap(display, root, 1, 1, 1/*depth*/);
  112.     xgc.function = GXclear;
  113.     gc =  XCreateGC(display, cursormask, GCFunction, &xgc);
  114.     XFillRectangle(display, cursormask, gc, 0, 0, 1, 1);
  115.     dummycolour.pixel = 0;
  116.     dummycolour.red = 0;
  117.     dummycolour.flags = 04;
  118.     cursor = XCreatePixmapCursor(display, cursormask, cursormask,
  119.           &dummycolour,&dummycolour, 0,0);
  120.     XFreePixmap(display,cursormask);
  121.     XFreeGC(display,gc);
  122.     return cursor;
  123. }
  124.  
  125. void CreateWindow(void)
  126. {
  127.  
  128.   // setup attributes for main window
  129.   int attribmask = CWEventMask  | CWColormap | CWBorderPixel;
  130.   XSetWindowAttributes attribs;
  131.   Colormap tmpcmap;
  132.  
  133.   tmpcmap = XCreateColormap(display, XRootWindow(display,
  134.                         x_visinfo->screen), my_visual, AllocNone);
  135.  
  136.   attribs.event_mask = StructureNotifyMask | KeyPressMask | KeyReleaseMask | ExposureMask;
  137.   attribs.border_pixel = 0;
  138.   attribs.colormap = tmpcmap;
  139.  
  140.   // create the main window
  141.   mainwin = XCreateWindow(display,
  142.             XRootWindow(display, x_visinfo->screen),
  143.             0, 0,    // x, y
  144.             win_xres+1, win_yres+1,
  145.             0, // borderwidth
  146.             x_visinfo->depth,
  147.             InputOutput,
  148.             my_visual,
  149.             attribmask,
  150.             &attribs );
  151.  
  152.   XFreeColormap(display, tmpcmap);
  153.  
  154. }
  155.  
  156. int *lookup24=NULL;
  157.  
  158. void palette::load()
  159. {
  160.  
  161.   int intensity;
  162.   int color;
  163.   int r, g, b;
  164.  
  165.   lookup24 = (int *)jmalloc(256*4,"24 bit palette lookup");
  166.   for (color = 0 ; color < 256 ; color++)
  167.   {
  168.     r = (int)red(color)<<24;
  169.     g = (int)green(color)<<16;
  170.     b = (int)blue(color)<<8;
  171.     lookup24[color] = r + g + b;
  172.   }
  173. }
  174.  
  175. void palette::load_nice()
  176. { load(); }
  177.  
  178. void image::make_page(short wid, short hi, unsigned char *page_buffer)
  179. {
  180.   if (special && !special->static_mem)
  181.   {
  182.     data=(uchar *)jmalloc(wid*hi,"image data\n");
  183.     if (page_buffer)
  184.       memcpy(data,page_buffer,wid*hi);
  185.   } else if (page_buffer)
  186.     data=page_buffer;
  187.   else data=(uchar *)jmalloc(wid*hi,"image data");
  188. }
  189.  
  190. void image::delete_page()
  191. {
  192.   if (!special || !special->static_mem)
  193.     jfree(data);      
  194. }
  195.  
  196. void reset_frame()
  197. {
  198.   glViewport(0, 0, win_xres+1, win_yres+1);
  199.   glMatrixMode(GL_PROJECTION);
  200.   glLoadIdentity();
  201.   gluOrtho2D(0, xres+1, 0, yres+1);
  202.   glMatrixMode(GL_MODELVIEW);
  203.   glLoadIdentity();
  204.  
  205.   xs=(float)(win_xres+1)/(xres+1);
  206.   ys=(float)(win_yres+1)/(yres+1);
  207.  
  208.   if (xs!=1.0 || ys!=1.0)
  209.     printf("Pixel scaling -> %lfx%lf\n",xs,ys);
  210.  
  211.   glPixelZoom(xs,ys);                    // top to bottom pixel lines
  212.   glRasterPos2i(0,0);
  213. }
  214.  
  215.  
  216. void Scaled_f(void)
  217. {
  218.     config_notify = 1;
  219.     glX_scaled = 1;
  220. }
  221.  
  222. void UnScaled_f(void)
  223. {
  224.     config_notify = 1;
  225.     glX_scaled = 0;
  226. }
  227.  
  228.  
  229. void set_mode(int mode, int argc, char **argv)
  230. {
  231. //  Cmd_AddCommand("glx_scaled", Scaled_f);
  232. //  Cmd_AddCommand("glx_unscaled", UnScaled_f);
  233.  
  234.  
  235.  
  236.   /****************************** Open DISPLAY *************************/
  237.   char display_name[100];
  238.   // get the default display name from the enviroment variable DISPLAY
  239.   char *ds_name=getenv("DISPLAY");
  240.   if (!ds_name) ds_name="unix:0.0";
  241.   strcpy(display_name,ds_name);   
  242.   display=XOpenDisplay(display_name);  
  243.   if (!display)
  244.   {
  245.     printf("Cound not connect to X server named '%s'\n",display_name);
  246.     exit(1);
  247.   }
  248.  
  249.   x_screen = DefaultScreen(display);
  250.  
  251.  
  252.   win_xres=640; win_yres=400;
  253.   int i;
  254.   for (i=1;i<argc;i++)
  255.   { if (!strcmp(argv[i],"-size"))
  256.     { i++; sscanf(argv[i],"%d",&win_xres);
  257.       i++; sscanf(argv[i],"%d",&win_yres);
  258.     }
  259.   }
  260.   xres=320;  yres=200;
  261.   PickVisual();
  262.  
  263.  
  264.   frame_buffer=(ulong *)jmalloc(xres*yres*4,"24 bit frame buffer\n");
  265.   screen=new image(xres,yres,NULL,2);
  266.   xres--;     yres--;
  267.   win_xres--; win_yres--;
  268.  
  269.   
  270.  
  271.   CreateWindow();
  272.  
  273.   glX_context = glXCreateContext(display, x_visinfo, 0, True);
  274.   glXMakeCurrent(display, mainwin, glX_context);
  275.  
  276.  
  277.   // ****************************  Create the Visual  ****************************
  278.   XGCValues xgcvalues;
  279.   int valuemask = GCGraphicsExposures;
  280.   xgcvalues.graphics_exposures = False;
  281.   x_gc = XCreateGC(display, mainwin, valuemask, &xgcvalues );
  282.  
  283.  
  284.   XDefineCursor(display, mainwin, CreateNullCursor(display, mainwin));
  285.  
  286.   XMapWindow(display, mainwin);
  287.  
  288.   XEvent event;
  289.   do
  290.   {
  291.     XNextEvent(display, &event);
  292.     if (event.type == Expose && !event.xexpose.count)
  293.       oktodraw = 1;
  294.   } while (!oktodraw);
  295.  
  296.   reset_frame();
  297.  
  298.   XSynchronize(display, False);
  299. }
  300.  
  301.  
  302. void close_graphics()
  303. {
  304.   jfree(frame_buffer);
  305.   delete screen;
  306.   XFreeGC(display,x_gc);
  307.   XFree((char *)my_visual);
  308.   XCloseDisplay(display);
  309. }
  310.  
  311.  
  312. static void refresh_frame_buffer(int x1, int y1, int x2, int y2)
  313. {
  314. /*  x1=x1&~3;
  315.   x2=(x2+3)&~3;*/
  316.  
  317. //  glRasterPos2i(0,yres);
  318.  
  319.  
  320. /*  glPixelStorei(GL_UNPACK_ROW_LENGTH,(xres+1));
  321.   glPixelStorei(GL_UNPACK_SKIP_PIXELS,x1);
  322.   glPixelStorei(GL_UNPACK_SKIP_ROWS,y1);
  323.   glRasterPos2i(0,0);*/
  324.  
  325. //  glDrawPixels(x2-x1+1,y2-y1+1, GL_RGBA, GL_UNSIGNED_BYTE,frame_buffer);
  326.   glRasterPos2i(x1,y1);
  327.   glDrawPixels(x2-x1+1,y2-y1+1, GL_RGBA, GL_UNSIGNED_BYTE,frame_buffer);
  328. //  glRecti(x1,y1,x2,y2);
  329.   glFlush();
  330.   glXSwapBuffers(display,mainwin);
  331. }
  332.  
  333. void put_part(image *im, int x, int y, int x1, int y1, int x2, int y2)
  334. {
  335.   int width=x2-x1+1,height=y2-y1+1,a,b;
  336.  
  337.   // first convert to 24 bit  
  338.   int size1=((long)im->width()*(long)im->height());
  339.  
  340.   
  341. //  ulong *page=frame_buffer+y*(xres+1)+x;
  342.   ulong *page=frame_buffer;
  343.   uchar *sl=im->scan_line(y1)+x1;
  344.   int skip=im->width()-(x2-x1+1);
  345.   int frame_skip=(xres+1)-(x2-x1+1);
  346.   for (y=y1;y<=y2;y++)
  347.   {
  348.     for (x=x1;x<=x2;x++)
  349.       *(page++)=lookup24[*(sl++)];
  350.     sl+=skip;
  351. //    page+=frame_skip;
  352.   } 
  353.   refresh_frame_buffer(x,y,x+(x2-x1),y+(y2-y1));
  354. }
  355.  
  356.  
  357. void put_image(image *im, int x, int y)
  358. { put_part(im,x,y,0,0,im->width()-1,im->height()-1); }
  359.  
  360.  
  361.  
  362. void update_dirty(image *im, int xoff, int yoff)
  363. {
  364.  
  365.   int count;
  366.   dirty_rect *dr,*q;
  367.   CHECK(im->special);  // make sure the image has the ablity to contain dirty areas
  368.   if (im->special->keep_dirt==0)
  369.     put_image(im,0,0);
  370.   else
  371.   {
  372.     count=im->special->dirties.number_nodes();
  373.     if (!count) return;  // if nothing to update, return
  374.     (linked_node *) dr=im->special->dirties.first();
  375.     while (count>0)
  376.     {
  377.       put_part(im,dr->dx1+xoff,dr->dy1+yoff,dr->dx1,dr->dy1,dr->dx2,dr->dy2);
  378.       q=dr;
  379.       (linked_node *)dr=dr->next();
  380.       im->special->dirties.unlink((linked_node *)q);
  381.       delete q;
  382.       count--;
  383.     }
  384.   }
  385. }
  386.  
  387.  
  388.  
  389.  
  390.  
  391.  
  392.  
  393.  
  394.